<template>
    <button open-type="chooseAvatar" @chooseavatar="bindchooseavatar" @click="uploadAvatarImg" class="box" :class="{'showBorder':border}"  :style="{width,height,lineHeight:height}">
        <cloud-image v-if="avatar_file" :src="avatar_file.url" :width="width" :height="height"></cloud-image>
        <uni-icons v-else :style="{width,height,lineHeight:height}" class="chooseAvatar" type="plusempty" size="30"
                   color="#dddddd"></uni-icons>
    </button>
</template>

<script>
import {
    store,
    mutations
} from '@/uni_modules/uni-id-pages/common/store.js'
/**
 * uni-id-pages-avatar 
 * @description 用户头像组件
 * @property {String} width	图片的宽，默认为：50px
 * @property {String} height	图片的高，默认为：50px
 */
export default {
    data() {
        return {
            isPC: false,
            quality: 80,
            maxSize: 1024
        }
    },
    props: {
        //头像图片宽
        width: {
            type: String,
            default () {
                return "50px"
            }
        },
        //头像图片高
        height: {
            type: String,
            default () {
                return "50px"
            }
        },
        border:{
            type: Boolean,
            default () {
                return false
            }
        }
    },
    async mounted() {
        // #ifdef H5
        this.isPC = !['ios', 'android'].includes(uni.getSystemInfoSync().platform);
        // #endif
    },
    computed: {
        hasLogin() {
            return store.hasLogin
        },
        userInfo() {
            return store.userInfo
        },
        avatar_file() {
            return store.userInfo.avatar_file
        }
    },
    methods: {
        setAvatarFile(avatar_file) {
            // 使用 clientDB 提交数据
            mutations.updateUserInfo({avatar_file})
        },
        async bindchooseavatar(res){
            let avatarUrl = res.detail.avatarUrl
            let avatar_file = {
                extname: avatarUrl.split('.')[avatarUrl.split('.').length - 1],
                name:'',
                url:''
            }
            try {
                avatarUrl = await this.compressImage(avatarUrl)
                await this.uploadToQiniu(avatarUrl, avatar_file)
            } catch (e) {
                console.error(e);
            }
            console.log('avatar_file',avatar_file);
            this.setAvatarFile(avatar_file)
        },
        uploadAvatarImg(res) {
            // #ifdef MP-WEIXIN
            return false // 微信小程序走 bindchooseavatar方法
            // #endif

            // #ifndef MP-WEIXIN
            if(!this.hasLogin){
                return uni.navigateTo({
                    url:'/uni_modules/uni-id-pages/pages/login/login-withpwd'
                })
            }
            const crop = {
                quality: 100,
                width: 600,
                height: 600,
                resize: true
            };
            uni.chooseImage({
                count: 1,
                crop,
                success: async (res) => {
                    let tempFile = res.tempFiles[0],
                        avatar_file = {
                            // #ifdef H5
                            extname: tempFile.name.split('.')[tempFile.name.split('.').length - 1],
                            // #endif
                            // #ifndef H5
                            extname: tempFile.path.split('.')[tempFile.path.split('.').length - 1]
                            // #endif
                        },
                        filePath = res.tempFilePaths[0]

                    //非app端剪裁头像，app端用内置的原生裁剪
                    // #ifdef H5
                    if (!this.isPC) {
                        filePath = await new Promise((callback) => {
                            uni.navigateTo({
                                url: '/uni_modules/uni-id-pages/pages/userinfo/cropImage/cropImage?path=' +
                                    filePath + `&options=${JSON.stringify(crop)}`,
                                animationType: "fade-in",
                                events: {
                                    success: url => {
                                        callback(url)
                                    }
                                },
                                complete(e) {
                                    console.log(e);
                                }
                            });
                        })
                    }
                    // #endif

                    try {
                        filePath = await this.compressImage(filePath)
                        await this.uploadToQiniu(filePath, avatar_file)
                    } catch (e) {
                        console.error(e);
                    }
                    this.setAvatarFile(avatar_file)
                }
            })
            // #endif
        },
        async uploadToQiniu(filePath, avatar_file) {
            uni.showLoading({
                title: "更新中",
                mask: true
            });

            const date = new Date()
            const year = date.getFullYear()
            const month = date.getMonth() + 1
            const day = date.getDate()
            const cloudPath = `public/avatar/${this.userInfo._id}/${Date.now()}_${Math.random().toString().slice(2, 7)}.webp`
            avatar_file.name = cloudPath

            // 使用扩展存储云对象上传
            const uniCloudStorageExtCo = uniCloud.importObject("ext-storage-co")
            const uploadFileOptionsRes = await uniCloudStorageExtCo.getUploadFileOptions({
                cloudPath: cloudPath,
                domain: "cdn.isscloud.site", // 域名地址
            })

            // 执行上传
            const uploadResult = await uni.uploadFile({
                ...uploadFileOptionsRes.uploadFileOptions,
                filePath: filePath,
            })

            const obj = JSON.parse(uploadResult.data)
            const fileID = `qiniu://${obj.key}`
            avatar_file.url = fileID

            uni.hideLoading()
        },
        async compressImage(filePath) {
            // 判断运行环境
            if (process.env.UNI_PLATFORM === 'h5') {
                // H5环境使用Canvas压缩
                try {
                    return await this.compressViaCanvas(filePath)
                } catch (compressErr) {
                    console.warn('Canvas压缩失败，使用原图上传', compressErr)
                    return filePath.replace(/\.[^/.]+$/, '') + '.webp'
                }
            } else if (uni.compressImage && typeof uni.compressImage === 'function') {
                // 小程序/App环境使用uni.compressImage
                try {
                    const compressedResult = await new Promise((resolve, reject) => {
                        uni.compressImage({
                            src: filePath,
                            quality: this.quality,
                            format: 'webp',
                            success: resolve,
                            fail: reject
                        })
                    })
                    return compressedResult.tempFilePath
                } catch (compressErr) {
                    console.warn('图片压缩失败，使用原图上传', compressErr)
                    return filePath.replace(/\.[^/.]+$/, '') + '.webp'
                }
            } else {
                console.warn('当前环境不支持压缩，使用原图上传')
                return filePath.replace(/\.[^/.]+$/, '') + '.webp'
            }
        },
        compressViaCanvas(filePath) {
            return new Promise((resolve, reject) => {
                const img = new Image()
                img.crossOrigin = 'Anonymous'
                img.src = filePath

                img.onload = () => {
                    try {
                        const canvas = document.createElement('canvas')
                        const ctx = canvas.getContext('2d')

                        // 计算压缩后的尺寸（保持宽高比）
                        let width = img.width
                        let height = img.height

                        if (width > this.maxSize || height > this.maxSize) {
                            const ratio = Math.min(this.maxSize / width, this.maxSize / height)
                            width = width * ratio
                            height = height * ratio
                        }

                        canvas.width = width
                        canvas.height = height
                        ctx.drawImage(img, 0, 0, width, height)

                        // 转换为WebP格式
                        canvas.toBlob((blob) => {
                            const compressedUrl = URL.createObjectURL(blob)
                            resolve(compressedUrl)
                        }, 'image/webp', this.quality / 100)
                    } catch (err) {
                        reject(err)
                    }
                }

                img.onerror = (err) => {
                    reject(new Error('图片加载失败'))
                }
            })
        }
    }
}
</script>

<style>
    /* #ifndef APP-NVUE */
    .box{
        overflow: hidden;
    }
    /* #endif */
    .box{
        padding: 0;
    }

    .chooseAvatar {
        /* #ifndef APP-NVUE */
        display: inline-block;
        box-sizing: border-box;
        /* #endif */
        border-radius: 10px;
        text-align: center;
        padding: 1px;
    }
    .showBorder{
        border: solid 1px #ddd;
    }
</style>    